package com.aizuda.boot.modules.third.wps.service;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.aizuda.boot.modules.third.wps.domain.dto.FileUploadMultiPhase;
import com.aizuda.boot.modules.third.wps.domain.entity.FileHistory;
import com.aizuda.boot.modules.third.wps.domain.vo.FileInfoVo;
import com.aizuda.boot.modules.third.wps.domain.vo.ResponseDTO;
import com.aizuda.boot.modules.third.wps.enums.DigestType;
import com.aizuda.boot.modules.third.wps.enums.WebOfficeErrEnum;
import com.aizuda.boot.modules.third.wps.exception.WebOfficeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * @author hjw
 * @description 文档编辑-三阶段保存
 * @date 2025年06月18日 14:46
 */
@Service
@Slf4j
public class MultiPhaseFileStorageService {

    @Autowired
    private FileHistoryService fileHistoryService;


    /**
     * 上传地址前缀
     */
    @Value("${file.storage.local.upload-new-url:#{null}}")
    private String uploadUrlPrefix;

    /**
     * 三阶段保存 - 准备上传阶段
     *
     * @param fileId 文件id <br>
     *               <a href = "https://solution.wps.cn/docs/callback/save.html#准备上传阶段">-详见官方文档-</a>
     */
    public List<DigestType> uploadPrepare(String fileId) {

        return Collections.singletonList(DigestType.SHA1);
    }

    /**
     * 三阶段保存 - 获取上传地址
     *
     * @param request 上传的文件 <br>
     *                <a href = "https://solution.wps.cn/docs/callback/save.html#获取上传地址">-详见官方文档-</a>
     */
    public FileUploadMultiPhase.FileUploadAddress.Response uploadAddress(FileUploadMultiPhase.FileUploadAddress.Request request) {

        return FileUploadMultiPhase.FileUploadAddress.Response.builder()
                .url(String.format(uploadUrlPrefix, request.getFileId()))
                .method(FileUploadMultiPhase.FileUploadAddress.Response.Method.PUT)
                .build();
    }


    /**
     * 三阶段保存 - 上传完成后，回调通知上传结果
     *
     * @param request 上传的文件 <br>
     *                <a href = "https://solution.wps.cn/docs/callback/save.html#上传完成后，回调通知上传结果">-详见官方文档-</a>
     */
    public FileInfoVo uploadComplete(FileUploadMultiPhase.FileUploadComplete.Request request) {

        Optional.of(request)
                .map(FileUploadMultiPhase.FileUploadComplete.Request::getResponse)
                .filter(r -> r.getStatus() == HttpStatus.OK.value())
                .orElseThrow(() -> new WebOfficeException(WebOfficeErrEnum.INVALID_REQUEST));

        FileUploadMultiPhase.FileUploadComplete.UploadResponse response = request.getResponse();
        String base64Body = response.getBody();

        log.debug("Response:{}", JSONUtil.toJsonStr(response));
        //base64 解码
        if (StrUtil.isBlank(base64Body)) {
            throw new WebOfficeException(WebOfficeErrEnum.INVALID_REQUEST);
        }
        String body = Base64.decodeStr(base64Body);
        //解析JSON
        ResponseDTO<String> bean = JSONUtil.toBean(body, ResponseDTO.class);
        String fileKey = bean.getData();


        //    根据fileKey 更新历史文件版本
        //    根据文件id加锁
        String fileId = request.getFileId();
        //ToDo 引入分布式锁
        //boolean lock = redisLockUtil.lock(fileId, fileKey, 60L);
        boolean lock = true;

        if (!lock) {
            throw new WebOfficeException(WebOfficeErrEnum.FILE_NOT_UPLOADED);
        }
        FileInfoVo fileInfoVo = new FileInfoVo();
        try {
            //  查询最新版本记录
            FileHistory latestHistory = fileHistoryService.lambdaQuery()
                    .eq(FileHistory::getFileId, fileId)
                    .isNotNull(FileHistory::getVersion)
                    .orderByDesc(FileHistory::getVersion)
                    .last("limit 1")
                    .one();
            int newVersion;
            if (ObjectUtil.isNull(latestHistory)) {
                newVersion = 2;
            } else {
                newVersion = latestHistory.getVersion() + 1;
            }
            //    根据fileKey获取历史信息
            FileHistory fileHistory = fileHistoryService.lambdaQuery().eq(FileHistory::getFileKey, fileKey).one();
            fileHistory.setVersion(newVersion);

            fileHistoryService.updateById(fileHistory);

            fileInfoVo = FileInfoVo.builder()
                    .id(fileHistory.getFileId().toString())
                    .name(fileHistory.getFileName())
                    .version(fileHistory.getVersion())
                    .size(fileHistory.getFileSize())
                    .createTime(fileHistory.getCreateTime().toInstant().getEpochSecond())
                    .modifyTime(fileHistory.getModifyTime().toInstant().getEpochSecond())
                    .creatorId(fileHistory.getCreatorId())
                    .modifierId(fileHistory.getModifierId())
                    .build();
        } finally {
            //redisLockUtil.releaseLock(fileId, fileKey);
        }

        //


        return fileInfoVo;
    }

}
